import type { WorkflowNode, WorkflowEdge } from '@/types/workflow'

// 验证节点
export const validateNode = (node: WorkflowNode): boolean => {
    try {
        // 验证基本字段
        if (!node.id || !node.type) {
            console.warn('Node missing required fields:', node)
            return false
        }

        // 验证输入参数
        if (node.inputs) {
            for (const [key, value] of Object.entries(node.inputs)) {
                if (!validateNodeInput(value)) {
                    console.warn('Invalid node input:', { node, key, value })
                    return false
                }
            }
        }

        return true
    } catch (error) {
        console.error('Node validation error:', error)
        return false
    }
}

// 验证节点输入
const validateNodeInput = (input: any): boolean => {
    if (input === null || input === undefined) {
        return false
    }

    if (typeof input === 'object') {
        // 验证对象类型的输入
        if (input.type && !['text', 'number', 'boolean', 'select'].includes(input.type)) {
            return false
        }
        if (input.type === 'select' && (!Array.isArray(input.options) || !input.options.length)) {
            return false
        }
    }

    return true
}

// 验证连接
export const validateEdge = (edge: WorkflowEdge, nodes: WorkflowNode[]): boolean => {
    try {
        // 验证基本字段
        if (!edge.id || !edge.source || !edge.target) {
            console.warn('Edge missing required fields:', edge)
            return false
        }

        // 验证源节点和目标节点存在
        const sourceNode = nodes.find(node => node.id === edge.source)
        const targetNode = nodes.find(node => node.id === edge.target)

        if (!sourceNode || !targetNode) {
            console.warn('Edge references non-existent nodes:', edge)
            return false
        }

        return true
    } catch (error) {
        console.error('Edge validation error:', error)
        return false
    }
}

// 验证整个工作流
export const validateWorkflow = (nodes: WorkflowNode[], edges: WorkflowEdge[]): boolean => {
    try {
        // 验证所有节点
        for (const node of nodes) {
            if (!validateNode(node)) {
                return false
            }
        }

        // 验证所有连接
        for (const edge of edges) {
            if (!validateEdge(edge, nodes)) {
                return false
            }
        }

        // 验证工作流完整性
        if (!validateWorkflowIntegrity(nodes, edges)) {
            return false
        }

        return true
    } catch (error) {
        console.error('Workflow validation error:', error)
        return false
    }
}

// 验证工作流完整性
const validateWorkflowIntegrity = (nodes: WorkflowNode[], edges: WorkflowEdge[]): boolean => {
    // 检查是否有孤立节点
    const connectedNodes = new Set<string>()
    edges.forEach(edge => {
        connectedNodes.add(edge.source)
        connectedNodes.add(edge.target)
    })

    const isolatedNodes = nodes.filter(node => !connectedNodes.has(node.id))
    if (isolatedNodes.length > 0) {
        console.warn('Workflow contains isolated nodes:', isolatedNodes)
        return false
    }

    // 检查是否有环
    if (hasCycle(nodes, edges)) {
        console.warn('Workflow contains cycles')
        return false
    }

    return true
}

// 检查是否有环
const hasCycle = (nodes: WorkflowNode[], edges: WorkflowEdge[]): boolean => {
    const visited = new Set<string>()
    const recursionStack = new Set<string>()

    const dfs = (nodeId: string): boolean => {
        visited.add(nodeId)
        recursionStack.add(nodeId)

        const outgoingEdges = edges.filter(edge => edge.source === nodeId)
        for (const edge of outgoingEdges) {
            if (!visited.has(edge.target)) {
                if (dfs(edge.target)) {
                    return true
                }
            } else if (recursionStack.has(edge.target)) {
                return true
            }
        }

        recursionStack.delete(nodeId)
        return false
    }

    for (const node of nodes) {
        if (!visited.has(node.id)) {
            if (dfs(node.id)) {
                return true
            }
        }
    }

    return false
} 